package com.db.bankapp.domain.bank;

import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @ThreadSafe
 * Represents bank client
 */
public class Client {
    private final AtomicLong idSeq = new AtomicLong();
    private final String name;
    private final Gender sex;
    private final Map<Long, Account> accounts = new LinkedHashMap<>();

    Client(String name, Gender sex, Account account) {
        this.name = name;
        this.sex = sex;
        if (account != null) {
            accounts.put(idSeq.incrementAndGet(), account);
        }
    }

    Client(String name, Gender sex) {
        this(name, sex, null);
    }

    /**
     * Adds clients account
     * @param account to add
     * @throws java.lang.NullPointerException when account is null
     */
    public void addAccount(Account account) {
        if (account == null) {
            throw new NullPointerException("Account should not be null!");
        }
        accounts.put(idSeq.incrementAndGet(), account);
    }

    /**
     * Returns copy of clients accounts
     * @return clients account
     */
    public Collection<Account> getAccounts() {
        return new LinkedHashSet<>(accounts.values());
    }

    /**
     * Returns account by id
     * @param id of account to return
     * @return account
     */
    public Account getAccount(long id) {
        return accounts.get(id);
    }

    /**
     * Returns and prints client salutation
     * @return client salutation
     */

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof Client )) return false;
        if (o instanceof Client) {
            return this.name.equals(((Client) o).name) && this.sex.equals(((Client) o).sex) && this.getAccount(1).equals(((Client) o).getAccount(1));
        }
        return false;
    }
    @Override
    public int hashCode() {
        int result=17;
        result = result*31+this.name.hashCode();
        result=result*31+ this.getAccount(1).hashCode();
        result =result*31 + this.sex.hashCode();
        return result;
    }

    public String toString() {
        StringBuffer salutation = new StringBuffer(sex.getSalutations()).append(name).append(" has " + this.getAccount(1).toString());

//        System.out.println(salutation); // it shouldn't print anything since its get
        return salutation.toString();
    }

}
